#ifndef VERTEX_H
#define VERTEX_H

class   Face;
class   Shader;
#include "Troll3D_global.h"
#include "BufferObject.h"
#include "GeoTool/vec4.h"
#include "Attributes.h"

#include <memory.h>
#include <vector>

/*!	@brief The Vertex class define the structure of vertex attributes send to the shaders, and the way to interact with them
 *
 *          Workflow overview : A mesh is constitued by vertices. All the vertex a Mesh need will be stored in only one
 *          vector : the static propertie Vertices in Vertex.
 *          When a mesh want to create a new Vertex, it'll have to call the static method "New", this will automatically add the vertex
 *          in the Vertices vector, and give back a pointer for the mesh
 *          To render the scene, the vertex must be given to a VBO as float *. So, there'll be a phase where all the vertex will be
 *          inspected and transformed in float * . During this phase, the m_Indice must be defined, for the IBO to work correctly
 */

class TROLL3DSHARED_EXPORT Vertex
{
    public :

        /************************************************/
        /*				Members 						*/
        /************************************************/

            /************************************************/
            /*				Properties 						*/
            /************************************************/

                Attributes *                m_Attributes;       /*!< Vertex attribute used by GLSL shaders      */
                std::vector<Face * >        m_Faces;            /*!< Faces connected to the current vertex		*/
                unsigned short              m_Index;            /*!< Index of the vertex, used by face to construct IBO and must be
                                                                 *   defined during float * construction         */

            /************************************************/
            /*				Methods 						*/
            /************************************************/

                /*!	The ToArray methods transform a Vertex in a float array ready to be inserted in a vbo	*/
                float *     ToArray();

                /*!	@brief The ComputeNormal method, as the name imply, will compute the normal of a vertex by making the means of all connected faces normals	*/
                void        ComputeNormal();

        /************************************************/
        /*				Statics 						*/
        /************************************************/

            /************************************************/
            /*				Properties 						*/
            /************************************************/

                static	std::vector<Vertex*>    Vertices;       /*!< Store all the application's Vertices on CPU side, not used for rendering, only editing	*/

            /************************************************/
            /*				Methods 						*/
            /************************************************/

                /*! @brief The Array method will transform every vertex in the static double vector to transform them for VBO insertion */
                static float *  Array();

                /*! All the static new function will be used to create Vertex inside meshes */
                static Vertex * New();
                static Vertex * New(vec4 * position);
                static Vertex * New(vec4 * position, vec4 * color);
                static Vertex * New(vec4 * position, vec4 * color, vec4 * normal);
                static Vertex * New(vec4 * position, vec4 * color, vec4 * normal, vec4 * texcoord0);

                static Vertex* InitNew(vec4 * position, vec4 * color, vec4 * normal, vec4 * texcoord0);

        /************************************************/
        /*				Constructors					*/
        /************************************************/

        void Init(vec4 * position, vec4 * color, vec4 * normal, vec4 * texCoord);

        Vertex(vec4 * position);
        Vertex(vec4 * position, vec4 * color);
        Vertex(vec4 * position, vec4 * color, vec4 * normal);
        Vertex(vec4 * position, vec4 * color, vec4 * normal, vec4 * texcoord0);

        Vertex(const Vertex * vertex);

};

#endif
